<template>
  <div class="app-container">
    <!-- 第一部分：页面标题与介绍 -->
    <div class="page-header" style="margin-top: 0px">
      <h3 class="page-title">ADE Identification Demo</h3>
      <p class="page-description">
        Analyze medical progress notes using provided prompts with selected LLM.
      </p>
    </div>

    <!-- 第二部分：信息输入部分 -->
    <el-card class="box-card">
      <template #header>
        <div class="clearfix">
          <span>Input Parameters</span>
        </div>
      </template>

      <el-form :inline="true" class="demo-form-inline" ref="queryform" :model="form" :rules="queryrules">
        <!--选择大语言模型-->
        <el-form-item label="LLM Model" prop="llmModel">
          <el-select v-model="form.llmModel" placeholder="Select LLM" size="mini" clearable>
            <el-option v-for="dict in dict.type.llm_model" :key="dict.value" :label="dict.label" :value="dict.value" />
          </el-select>
        </el-form-item>

        <!--选择Prompt-->
        <el-form-item label="Prompt Template" prop="promptId">
          <el-select v-model="form.promptId" placeholder="Select Prompt" size="mini" @change="handlePromptChange"
            clearable>
            <el-option v-for="dict in prompts" :key="dict.id" :label="dict.identifier" :value="dict.id" />
          </el-select>
        </el-form-item>

        <el-form-item style="margin-right: 50px;">
          <el-checkbox v-model="form.afterFilter">Ade Filter</el-checkbox>
        </el-form-item>

        <el-form-item>
          <el-button type="primary" size="mini" icon="el-icon-refresh" @click="randomEmr" :loading="nexting">Random
            Case</el-button>
          <el-button type="success" size="mini" icon="el-icon-search" @click="recognizeADE"
            :loading="loading">Analyze</el-button>
          <el-button type="info" size="mini" icon="el-icon-document" @click="openSaveCase">Report Case</el-button>
        </el-form-item>
      </el-form>

      <!--RAG相关配置-->
      <!--RAG 模式下 知识库检索相关配置-->
      <el-form :inline="true" v-if="isRagPrompt" :model="form" :rules="queryrules" ref="ragform">

        <!--选择 ADE 库-->
        <el-form-item label="ADE KB" prop="adekbid">
          <el-select v-model="form.adekbid" placeholder="Select ADE KB" size="mini" clearable style="width:150px">
            <el-option v-for="dict in adekbs" :key="dict.id" :label="dict.name" :value="dict.id" />
          </el-select>
        </el-form-item>

        <!--选择切分方式-->
        <el-form-item label="Chunk Type" prop="chunkType">
          <el-select v-model="form.chunkType" placeholder="Select Chunk Type" size="mini" clearable style="width:150px">
            <el-option v-for="dict in dict.type.chunk_type" :key="dict.value" :label="dict.label" :value="dict.value" />
          </el-select>
        </el-form-item>

        <!--选择embed模型
        <el-form-item label="Embed Model" prop="embedModel">
          <el-select v-model="form.embedModel" placeholder="Select Embedding Model" size="mini" clearable>
            <el-option v-for="dict in dict.type.embed_models" :key="dict.value" :label="dict.label"
              :value="dict.value" />
          </el-select>
        </el-form-item>
        -->

        <!--选择相似度阀值-->
        <el-form-item label="Sim Score" prop="simScore">
          <el-input-number v-model="form.simScoreThreshold" placeholder="Similarity Score" style="width:100px" />
        </el-form-item>

        <!--选择topN-->
        <el-form-item label="TopN" prop="topN">
          <el-input-number v-model="form.topN" placeholder="Top N" :min="1" :max="100" style="width:100px" />
        </el-form-item>

      </el-form>

      <!--病程记录内容-->
      <el-form ref="emrform" :model="form" :rules="queryrules">
        <el-form-item label="Medical Record" prop="emr">
          <el-input type="textarea" :rows="6" v-model="form.emr"
            placeholder="Please input medical record content..."></el-input>
        </el-form-item>
      </el-form>
    </el-card>

    <!-- 第三部分：ADE Identification Result -->
    <el-card class="box-card" v-loading="loading">
      <template #header>
        <div class="clearfix" style="text-align: center; font-weight: 600">
          <span>ADE Identification Result</span>
        </div>
      </template>

      <!-- 第一行：病历内容标注结果展示 -->
      <el-row :gutter="20">
        <el-col :span="24">
          <el-card class="result-card">
            <div slot="header" class="clearfix">
              <span>Annotated Medical Record</span>
              <el-button style="float: right; padding: 3px 0" type="text">
                <el-tooltip content="Highlighted ADE terms in medical record" placement="top">
                  <i class="el-icon-question"></i>
                </el-tooltip>
              </el-button>
            </div>

            <div v-html="formatEmr" class="annotated-text">
            </div>
          </el-card>
        </el-col>
      </el-row>

      <!-- 第二行：Ades识别结果JSON展示、Prompt提示词展示 -->
      <el-row :gutter="20" style="margin-top: 20px">
        <el-col :span="12">
          <el-card class="result-card">
            <div slot="header" class="clearfix">
              <span>ADE Entities</span>
              <el-button style="float: right; padding: 3px 0" type="text">
                <el-tooltip content="Extracted ADE entities in JSON format" placement="top">
                  <i class="el-icon-question"></i>
                </el-tooltip>
              </el-button>
            </div>
            <pre class="json-result">{{ jsonText }}</pre>
          </el-card>
        </el-col>
        <el-col :span="12">
          <el-card class="result-card">
            <div slot="header" class="clearfix">
              <span>Used Prompt</span>
              <el-button style="float: right; padding: 3px 0" type="text">
                <el-tooltip content="The prompt template used for analysis" placement="top">
                  <i class="el-icon-question"></i>
                </el-tooltip>
              </el-button>
            </div>
            <pre class="prompt-text">{{ prompt }}</pre>
          </el-card>
        </el-col>
      </el-row>
    </el-card>

    <!-- 添加或修改Ade Cases对话框 -->
    <el-dialog :title="title" :visible.sync="open" width="75%" append-to-body>
      <el-form ref="caseform" :model="caseForm" :rules="rules">
        <el-form-item label="Content" prop="content">
          <el-input v-model="caseForm.content" type="textarea" rows="5" placeholder="Pls input content" />
        </el-form-item>
        <el-form-item label="Ades" prop="ades">
          <el-input v-model="caseForm.ades" type="textarea" rows="5" placeholder="Pls input ades(json format)" />
        </el-form-item>
        <el-form-item label="LLM" prop="llm">
          <el-select v-model="caseForm.llm" placeholder="Select LLM">
            <el-option v-for="dict in dict.type.llm_model" :key="dict.value" :label="dict.label"
              :value="dict.value"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="PromptType" prop="promptType">
          <el-select v-model="caseForm.promptType" placeholder="Select PromptType">
            <el-option v-for="dict in dict.type.prompt_type" :key="dict.value" :label="dict.label"
              :value="dict.value"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="Case Type" prop="type">
          <el-select v-model="caseForm.type" placeholder="Select Case Type">
            <el-option v-for="dict in dict.type.ade_case_type" :key="dict.value" :label="dict.label"
              :value="dict.value"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="Description" prop="description">
          <el-input v-model="caseForm.description" type="textarea" rows="5" placeholder="Pls input description" />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitCaseForm">Confirm</el-button>
        <el-button @click="cancel">Cancel</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { listAllAdebase } from "@/api/ade/adebase";
import { recognize } from "@/api/ade/adeRecognition";
import { randomStandard } from "@/api/ade/standard";
import { addCase } from "@/api/ade/case";
import { listAllPrompt } from "@/api/ade/prompt";

export default {
  name: "AdeApp2",
  dicts: [
    "llm_model",
    "ade_knowledge",
    "chunk_type",
    "ade_case_type",
    "prompt_type",
  ],
  data() {
    return {
      // 所有的Prompt
      prompts: [],
      isRagPrompt: false, // 是否是RAG类型的Prompt
      promptType: "", // 默认Prompt类型
      //ADE请求体
      form: {
        emr: "", // 病历内容
        promptId: "", // Prompt ID
        llmModel: "ernie-3.5-8k", // LLM模型
        afterFilter: true, // 是否启用后处理
        chunkType: 'mark',  //切分方式
        simScoreThreshold: 0.7,   //相似度阈值
        topN: 5,  //返回结果数量
        debug: false, //是否启用ADE过滤
        adekbid: null, // ADE知识库ID
      },
      adekbs: [], //ADE知识库列表

      //ADE Case 表单
      caseForm: {
        content: null, // 病历内容
        ades: null, // ADE识别结果
        llm: null, // LLM模型
        promptType: null, // Prompt类型
        type: null, // 案例类型
        description: null, // 案例描述
      },
      title: "", //对话框名称
      open: false, //是否显示对话框
      // 表单校验
      queryrules: {
        llmModel: [
          {
            required: true,
            message: "LLM Model can not be empty!",
            trigger: "change",
          },
        ],
        promptId: [
          {
            required: true,
            message: "Prompt Template can not be empty!",
            trigger: "change",
          },
        ],
        emr: [
          {
            required: true,
            message: "Medical Record can not be empty!",
            trigger: "blur",
          },
        ],
        adekbid: [
          { required: true, message: "Please select an ADE knowledge base", trigger: "change" }
        ],
        embedModel: [
          { required: true, message: "Please select an embedding model", trigger: "change" }
        ],
        chunkType: [
          { required: true, message: "Please select a chunk type", trigger: "change" }
        ],
        simScore: [
          { type: 'number', min: 0, max: 1, message: "Similarity score must be between 0 and 1", trigger: "blur" }
        ]
      },
      rules: {
        content: [
          {
            required: true,
            message: "Content can not be empty!",
            trigger: "blur",
          },
        ],
        ades: [
          {
            required: true,
            message: "Ades can not be empty!",
            trigger: "blur",
          },
        ],
        llm: [
          {
            required: true,
            message: "LLM can not be empty!",
            trigger: "change",
          },
        ],
        promptType: [
          {
            required: true,
            message: "PromptType can not be empty!",
            trigger: "change",
          },
        ],
        type: [
          {
            required: true,
            message: "Case Type can not be empty!",
            trigger: "change",
          },
        ],
        description: [
          {
            required: true,
            message: "Description can not be empty!",
            trigger: "blur",
          },
        ],

      },

      // JSON数据
      jsonText: "",
      //识别后的EMR
      formatEmr: "",
      // 请求的Prompt
      prompt: "",
      // 状态
      loading: false,
      nexting: false,
    };
  },
  computed: {},
  created() {
    // 获取所有的Prompt
    this.getAllPrompts();
    // 初始化JSON文本
    this.randomEmr();
  },
  methods: {
    // 处理Prompt选择变化
    // 根据当前prompt ID 获取到prompt对象 
    handlePromptChange(vaue) {
      const selectedPrompt = this.prompts.find(prompt => prompt.id === vaue);
      if (selectedPrompt) {
        if (selectedPrompt.type === "RAG") {
          this.isRagPrompt = true; // 如果是RAG类型的Prompt
          // 初始化时加载ADE知识库列表
          this.listallAdebases();
        } else {
          this.isRagPrompt = false; // 如果不是RAG类型的Prompt
        }
        this.promptType = selectedPrompt.type; // 设置当前Prompt类型
      } else {
        this.isRagPrompt = false; // 如果没有找到对应的Prompt，重置为非RAG类型
        this.promptType = ''; // 重置Prompt类型
        //this.$message.error("Selected prompt not found");
      }
    },
    //获取所有的ADE知识库
    listallAdebases() {
      var data = { status: '' };
      // Fetch all ADE knowledge bases
      listAllAdebase(data).then(response => {
        this.adekbs = response.data;
        if (this.adekbs.length > 0) {
          this.form.adekbid = this.adekbs[0].id; // 默认选择第一个ADE知识库
        }
      }).catch(error => {
        this.$message.error("Failed to load ADE knowledge bases: " + error.message);
      });
    },
    getAllPrompts() {
      // 获取所有的Prompt
      listAllPrompt().then((response) => {
        this.prompts = response.data;
      });
    },
    // 随机病例
    randomEmr() {
      this.nexting = true;
      var data = { status: "", source: "" };
      randomStandard(data)
        .then((response) => {
          if (response.data == null || response.data == undefined) {
            this.$message.warning(
              "No aviliable emr data, please change the source or status!"
            );
            this.nexting = false;
            return;
          }
          this.form.emr = response.data.content;
          this.nexting = false;

          //成功获取到数据 要将前一个数据的ADE结果清空
          this.formatEmr = "";
          this.jsonText = "";
          this.prompt = "";
        })
        .catch((error) => {
          this.$message.error("Too fast, please wait a moment!");
          this.nexting = false;
        });
    },
    //ADE识别
    recognizeADE() {
      console.log("Recognizing ADE with form:", this.form);
      this.$refs["queryform"].validate((valid) => {   //验证基本表单信息
        if (!valid) {
          return;
        }
        // 验证RAG相关表单
        if (this.isRagPrompt) {
          let r = false;
          this.$refs["ragform"].validate((valid1) => {  //验证RAG相关表单
            r = valid1;
          });
          if (!r) {
            return;
          }
        }

        this.$refs["emrform"].validate((valid2) => {  //验证病历内容
          if (!valid2) {
            return;
          }
          //识别之前要将前一个数据的ADE结果清空
          this.formatEmr = "";
          this.jsonText = "";
          this.prompt = "";

          this.loading = true;
          this.nexting = true;
          recognize(this.form)
            .then((response) => {
              this.jsonText = JSON.stringify(response.data.ades, null, 2);
              // 设置请求的Prompt
              this.prompt = response.data.prompt || "No prompt provided";
              // 格式化EMR内容，突出显示识别出的ADE
              let rep = "";
              this.formatEmr = this.form.emr; // 初始化格式化的EMR内容
              for (let i = 0; i < response.data.ades.length; i++) {
                rep = response.data.ades[i].sentence; // 将其他ADE名称用 | 分隔
                this.formatEmr = this.formatEmr.replaceAll(
                  rep,
                  '<font color="red">' + rep + "</font>"
                );
              }
              this.loading = false;
              this.nexting = false;
            })
            .catch((error) => {
              this.$message.error("Failed to recognize ADE");
              this.loading = false;
              this.nexting = false;
              this.jsonText = "";
            });

        });
      });
    },
    //=============================================新增案例=========================
    // 取消按钮
    cancel() {
      this.open = false;
      this.resetForm("caseform");
    },
    //打开保存case对话框
    openSaveCase() {
      this.resetForm("caseform");
      this.title = "Save Case";
      this.caseForm.content = this.form.emr;
      this.caseForm.ades = this.jsonText ? this.jsonText : "[]";
      this.caseForm.llm = this.form.llmModel;
      this.caseForm.promptType = this.promptType ? this.promptType : "SAG";
      this.caseForm.source = "ADE Recognition";
      this.open = true;
    },
    /** 提交按钮 */
    submitCaseForm() {
      this.$refs["caseform"].validate((valid) => {
        if (valid) {
          addCase(this.caseForm).then((response) => {
            this.$modal.msgSuccess("Report Case Successfully!");
            this.open = false;
          });
        }
      });
    },
  },
};
</script>

<style scoped>
.box-card {
  margin-bottom: 10px;
}

.page-header {
  margin-bottom: 20px;
}

.page-title {
  margin-top: 5px;
  font-size: 22px;
  color: #303133;
  margin-bottom: 0px;
  font-weight: bold;
}

.page-description {
  font-size: 16px;
  color: #606266;
  line-height: 1.5;
}

.result-card {
  height: 100%;
}

.annotated-text {
  min-height: 120px;
  font-size: 13px;
  padding: 15px;
  background-color: #f5f7fa;
  border-radius: 4px;
  line-height: 1.4;
}

.ade-term {
  background-color: #ffcccc;
  padding: 0 3px;
  border-radius: 2px;
}

.drug-term {
  background-color: #ccffcc;
  padding: 0 3px;
  border-radius: 2px;
}

.json-result,
.prompt-text {
  min-height: 180px;
  padding: 15px;
  background-color: #f5f7fa;
  border-radius: 4px;
  overflow: auto;
  font-size: 13px;
  white-space: pre-wrap;
  line-height: 1.4;
}
</style>